package com.neusoft.doub;

import com.neusoft.entity.Hero;

import java.util.Objects;

/**
 * @author lichunlong lcl253137@alibaba-inc.com
 * @desc 双向链表实现类
 * @date 2024-06-11
 */
public class DoubleLinkedList {

    /**
     * 先初始化一个头节点, 头节点不动, 不存放具体的数据
     */
    private final Node<Hero> headNode = new Node<>();

    /**
     * 获取headNode头结点
     *
     * @return 头结点
     */
    public Node<Hero> getHeadNode() {
        return headNode;
    }

    /**
     * 遍历打印链表中的数据
     */
    public void list() {
        // 判断链表是否为空
        if (Objects.isNull(headNode.next)) {
            System.out.println("双向链表为空");
            return;
        }
        // 因为headNode头节点不能动，因此需要一个tempNode辅助节点
        Node<Hero> tempNode = headNode.next;
        while (Objects.nonNull(tempNode)) {
            // 输出节点的信息
            System.out.println(tempNode.getItem());
            // 后移tempNode
            tempNode = tempNode.next;
        }
    }

    /**
     * 添加节点
     *
     * @param node 新增节点
     */
    public void add(Node<Hero> node) {
        // 因为head节点不能动，因此需要一个tempNode辅助节点
        Node<Hero> tempNode = headNode;

        while (Objects.nonNull(tempNode.next)) {
            // 如果没有找到最后, 将将temp后移
            tempNode = tempNode.next;
        }

        // 当退出while循环时，temp就指向了链表的最后; 将最后这个节点的next指向新的节点
        tempNode.next = node;
        node.pre = tempNode;
    }

    /**
     * 更新节点: 根据Hero#no编号来修改，即Hero#no编号作为唯一主键
     *
     * @param heroNode 水浒英雄节点
     */
    public void update(Node<Hero> heroNode) {
        // 判断链表是否为空
        if (Objects.isNull(headNode.next)) {
            System.out.println("链表为空, 无法更新");
            return;
        }

        // 因为headNode头节点不能动，因此需要一个tempNode辅助节点
        Node<Hero> tempNode = headNode.next;
        boolean updateFlag = false;
        while (Objects.nonNull(tempNode)) {
            if (tempNode.getItem().getNo() == heroNode.getItem().getNo()) {
                // 根据Hero#no编号已经找到对应节点
                tempNode.setItem(heroNode.getItem());
                updateFlag = true;
                break;
            }
            // 后移tempNode
            tempNode = tempNode.next;
        }

        System.out.println(updateFlag ? "更新成功" : "未成功找到数据, 无法更新");
    }

    /**
     * 删除节点
     *
     * @param heroNodeNo 水浒英雄no编号
     */
    public void delete(Integer heroNodeNo) {
        // 判断链表是否为空
        if (Objects.isNull(headNode.next)) {
            System.out.println("链表为空, 无法删除");
            return;
        }

        Node<Hero> tempNode = headNode.next;
        boolean deleteFlag = false;
        while (Objects.nonNull(tempNode)) {
            if (tempNode.getItem().getNo() == heroNodeNo) {
                tempNode.pre.next = tempNode.next;
                // 安全限制: 当前节点是最后一个节点的情况
                if (Objects.nonNull(tempNode.next)) {
                    tempNode.next.pre = tempNode.pre;
                }

                deleteFlag = true;
                break;
            }
            // 后移tempNode
            tempNode = tempNode.next;
        }

        System.out.println(deleteFlag ? "删除成功" : "未成功找到数据, 无法删除");
    }
}
